/**
 * 
 */
package cn.agiledata.bank.account.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.agiledata.bank.account.dao.IAccountDAO;
import cn.agiledata.bank.common.exception.BusinessException;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.StringUtil;
import cn.agiledata.bank.common.util.WeatherUtil;
import cn.agiledata.bank.facade.IUserSummary;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.AccountBalance;
import cn.agiledata.bank.hibernateBean.OperSubacct;
import cn.agiledata.bank.hibernateBean.OperSubacctId;
import cn.agiledata.bank.hibernateBean.Operator;
import cn.agiledata.bank.hibernateBean.SubAccount;
import cn.agiledata.bank.hibernateBean.Sysbook;
import cn.agiledata.bank.hibernateBean.SystemLog;
import cn.agiledata.bank.myspace.service.AuthenticateService;
import cn.agiledata.bank.myspace.service.IMySpaceService;
import com.vnv.infrastructure.logic.IPBAppFactory;

/**
 * @author 马贤波
 *
 * Apr 3, 2006
 */
public class AccountSummary extends HibernateDaoSupport implements Serializable, IAccountConst,Constant {
	
	private static Log log = LogFactory.getLog(AccountSummary.class);
	
	public static AccountSummary NULL = null ;
	private String root = "";
	private IUserSummary user = null ;
	public IUserSummary getUser() {
		if(this.user == null) {
			DefaultUserSummary user = new DefaultUserSummary() ;
			user.setUserId(this.account.getId()) ;
			String name = this.account.getName() ;
			
			if (Constant.ACCOUNT_TYPE_CORPORATION.equals
					(this.account.getAccountType()))
				name = this.getOperatorName();
			
			if(name == null) {
				name = this.account.getEmail() ;
			}
			if(name == null) {
				name = this.account.getMobile() ;
			}
			if(name == null) {
				name = "用户" ;
			}
			user.setUsername(name) ;
			user.setSectionAuthors(this.getAuthSections()) ;
			user.setLastLogin(getLastvisit()) ;
			String auditStatus = this.account.getAuditStatus();
			String accountType = this.account.getAccountType();
			if(!StringUtil.isStrEmpty(auditStatus)) {
				if(!StringUtil.isStrEmpty(accountType) && accountType.equals(ACCOUNT_TYPE_CORPORATION)) {
					if(auditStatus.equals(NO_AUDIT_STATUS)) {
						user.setAuditStatus("(未审核)");
					}
					if(auditStatus.equals(IN_AUDIT_STATUS)) {
						user.setAuditStatus("(审核中)");
					}
					if(auditStatus.equals(HAVE_AUDIT_STATUS)) {
						user.setAuditStatus("(已审核)");
					}					
				}	
			}
			
			user.setAccountType(this.account.getAccountType());
			
			this.user = user ;
		}
		
		return this.user ;
	}
	
	private IAccountDAO dao ; //服务代理
	public IAccountDAO getDAO () { return dao ;}
	
	private List authSections = new ArrayList() ;
	public List getAuthSections()  { 
		return this.authSections != null ? this.authSections : new ArrayList()  ;
	}
	public void setAuthSections(List sections) {this.authSections = sections ;}
	
	private SystemLog sysLog ; //登录日志
	
	private Account account ; //账户实体
	private Operator operator = null ; //操作员实体
	
	private String paymentPassword ; //支付口令
	
	private long selectedSubAccountId = -1 ; //当前选择子账户
	private long defaultSubAccountId ; //默认子账户
	private List subAccountDigisters = new ArrayList () ; //所有子账户摘要
	private List subAccounts ;  //所有子账户
	
	private List operatorList = new ArrayList (); //所有操作员
	public List getOperatorList() {
		this.loadOperatorList();
		return this.operatorList ;
	}
	
	private AuthenticateService getAuthenticateService() {
		return (AuthenticateService) IPBAppFactory
				.getObj("authenticateService");
	}
	
	public AccountSummary (IAccountDAO dao,  Account account, Operator operator) {
		this.dao = dao ;
		this.account= account ;
		this.operator = operator ;
		
		if (operator != null) {
			this.paymentPassword = operator.getPayPassword() ;
		}else {
			this.paymentPassword = account.getPayPassword() ;
		}
		
		this.subAccountDigisters = this.dao.getSubAccountDigisters(account) ;
		
		if (account.getDefaultSubAccount() != null) {
			this.defaultSubAccountId = account.getDefaultSubAccount().getId().longValue() ;
		}else {
			if(subAccountDigisters != null && subAccountDigisters.size()!=0) {
				this.defaultSubAccountId = ((SubAccountDigister)this.subAccountDigisters.get(0)).getId() ;
			}
		}
	
		//选择当前子账户
		this.selectedSubAccountId = this.defaultSubAccountId ;
		
		this.loadOperatorList() ;
		
	}
	
	private void loadOperatorList () {
		if (USERTYPE_CORP_ADMIN.equals(this.getUserType())) {
			this.operatorList = this.dao.getOperatorsOfAccount(this.account) ;
		}
	}
	
	public boolean isEnterprise () {
		return Constant.ACCOUNT_TYPE_CORPORATION.equals(this.account.getAccountType())
		|| Constant.ACCOUNT_TYPE_INITIAL.equals(this.account.getAccountType());
	}
	
	public String getUserType () {
		if (isEnterprise() && this.operator == null) {
			return USERTYPE_CORP_ADMIN ;
		}else if ( isEnterprise() && this.operator != null) {
			return USERTYPE_CORP_OPERATOR ;
		}else {
			return USERTYPE_PERSONAL ;
		}
		
	}
	//edit by wubo 20080324 start
	public String getCompanyType() {
		return this.account.getCompanyType();
	}
	//edit by wubo 20080324 end
	
	public String getPaymentPassword() {
		return paymentPassword;
	}

	public void setPaymentPassword(String paymentPassword) {
		this.paymentPassword = paymentPassword;
	}

	/** 获取类型名 */
	public String getAccountTypeName () {
		if (Constant.ACCOUNT_TYPE_BUYER.equals(this.account.getAccountType())) {
			return TYPENAME_PERSONAL ;
		}else if  (Constant.ACCOUNT_TYPE_CORPORATION.equals(this.account.getAccountType())) {
			return TYPENAME_ENTERPRISE ;
		}
		return TYPENAME_OTHER ;
	}
	
	/** 获取账户ID */
	public long getAccountId() {
		return this.account.getId().longValue() ;
	}
	
	/** 获取账户状态 */
	public String getAccountStatus() {
		return this.account.getStatus() ;
	}
	
	/** 获取账号名 */
	public String getAccountName () {
		return this.account.getName() ;
	}
	
	public void setAccountMobile (String mobile) {
		Account account = this.dao.getAccountById(new Long(this.getAccountId()));
		account.setMobile(mobile) ;
		if(!"".equals(mobile)){
			getAuthenticateService().setMobileTelAuthenticationStatus(account,
					Constant.AUTHENTICATION_STATUS_PASS);
		}else{
			getAuthenticateService().setMobileTelAuthenticationStatus(account,
					Constant.AUTHENTICATION_STATUS_UNPASS);
		}
		this.dao.updateAccount(account) ;
		
	}
    //add by tony
    public void setAccountMobile () {
        Account account = this.dao.getAccountById(new Long(this.getAccountId()));
        account.setMobile("");
        account.setMobActiveCode("");
        account.setMobStatus(Constant.ACCOUNT_STATE_INVALID);
        getAuthenticateService().setMobileTelAuthenticationStatus(account,Constant.AUTHENTICATION_STATUS_UNPASS);
        this.dao.updateAccount(account) ;
    }
	//add by given
	public void setAccountEmail() {
		Account account = this.dao.getAccountById(new Long(this.getAccountId()));
		account.setEmail("");
		account.setActiveCode("");
		account.setEmStatus(Constant.ACCOUNT_STATE_INVALID) ; //账户无效
		this.dao.updateAccount(account) ;
	}
	
	/** 
	 * 获取操作员名.
	 * 如果是个人，就是个人姓名；如果是企业，就是管理员或操作人名
	 */
	public String getOperatorName () {
		
		if (! isEnterprise()) {
			return this.account.getName() ;
		}
		
		if (this.operator == null) {
			return ADMIN_OPERATOR_NAME ;
		}else {
			return this.operator.getOperatorName() ;
		}
	}
	
	/**
	 * 这里的代号可能是供操作历史记录使用，所以都是主键
	 * @return
	 */
	public Long getOperatorCode () {
		if (this.operator != null) {
			return this.operator.getId() ;
		}else {
			return null ;
		}
	}

	public long getSelectedSubAccountId() {
		return selectedSubAccountId == -1 ? this.getDefaultSubAccountId() : selectedSubAccountId;
	}

	public void setSelectedSubAccountId(long selectedSubAccountId) {
		this.selectedSubAccountId = selectedSubAccountId;
	}
	

	/**
	 * @return Returns the subAccounts.
	 */
	public List getSubAccountDigisters() {
		return subAccountDigisters;
	}
	
	public List getSubAccountList () {
		this.subAccounts = this.dao.getSubAccountOfAccount(this.account) ;
		return this.subAccounts ;
	}

	public List getSubAccountListV () {
		this.subAccounts = this.dao.getSubAccountOfAccountV(this.account) ;
		return this.subAccounts ;
	}
	
	/**
	 * @return Returns the defaultSubAccountId.
	 */
	public long getDefaultSubAccountId() {
		return defaultSubAccountId;
	}

	/**
	 * @param defaultSubAccountId The defaultSubAccountId to set.
	 */
	public void setDefaultSubAccountId(long defaultSubAccountId) {
		this.defaultSubAccountId = defaultSubAccountId;
	}
	
	public SubAccount getSubAccountById (String id) { 
		SubAccount  result = null ;
		for (int i = 0 ; i < this.subAccounts.size() ; i ++) {
			result = (SubAccount) this.subAccounts.get(i) ; 
			if (result.getId().toString().equals(id)) {
				return result ;
			}
		}
		
		return null ;
	}

	public void addSubAccount (String acountId, String name, String detailFlag,String remark) throws BusinessException {
		
		try {
			int count = this.dao.findCountOfSubAccount (this.account.getId().longValue(), acountId, null) ;
			if (count > 0) {
				throw BusinessException.ACCOUNT_SUBID_DUPLICATED ;
			}
			
			SubAccount sub = new SubAccount () ;
			sub.setAccount(this.account) ;
			//account.getSubAccounts().add(sub) ;
			
			sub.setAccountId(acountId) ;
			sub.setAccountName(name) ;
			sub.setValidFlag("Y") ;
			sub.setDetailFlag(detailFlag);
			sub.setRemark(remark) ;
			/*sub.setCreateUser(this.account.getId().toString());
			sub.setCreateTime(new Date()) ;
			sub.setUpdateUser(this.account.getId().toString()) ;
			sub.setUpdateTime(new Date()) ;*/
			WeatherUtil.fillCreateAndUpdateInfo(sub, this.account.getId().toString());
			sub.setSubAccountType("0");
			sub.setIvrFlag("N");
			
			AccountBalance balance = new AccountBalance () ;
			balance.setBalance(Double.valueOf("0.0")) ;
			balance.setLockAmount(new Double("0.0"));
			/*balance.setCreateUser(this.account.getId().toString()) ;
			balance.setCreateTime(new Date()) ;
			balance.setUpdateUser(this.account.getId().toString()) ;
			balance.setUpdateTime(new Date()) ;*/
			WeatherUtil.fillCreateAndUpdateInfo(balance, this.account.getId().toString());
			balance.setSubAccount(sub) ;
			sub.setAccountBalance(balance) ;
			
			this.dao.addOrUpdateSubAccount(sub) ;
			//更新子账户摘要
			this.subAccountDigisters = this.dao.getSubAccountDigisters(account) ;
			if(detailFlag.equals("Y")) {
				this.dao.updateOtherAccountDetailFlag(sub.getAccount().getId(),sub.getId());
			}
		} catch (DataAccessException e) {
			log.error("数据库操作错误", e) ;
			throw BusinessException.INFRA_FAILURE ;
		}
	}
	
	public void updateSubAccount (String id, String acountId, String name, String detailFlag,String remark) throws BusinessException {
		try {
			int count = this.dao.findCountOfSubAccount (this.account.getId().longValue(), acountId, Long.valueOf(id)) ;
			if (count > 1) {
				throw BusinessException.ACCOUNT_SUBID_DUPLICATED ;
			}
			
			SubAccount sub = this.getSubAccountById(id) ;
			if (sub != null) {
				sub.setAccountId(acountId) ;
				sub.setAccountName(name) ;
				sub.setDetailFlag(detailFlag);
				sub.setRemark(remark) ;
				sub.setSubAccountType("0");
				this.dao.addOrUpdateSubAccount(sub) ;
				this.subAccountDigisters = this.dao.getSubAccountDigisters(account) ;
				if(detailFlag.equals("Y")) {
					this.dao.updateOtherAccountDetailFlag(sub.getAccount().getId(),sub.getId());
				}
			}else {
				throw BusinessException.INFRA_FAILURE ;
			}
		} catch (DataAccessException e) {
			log.error("数据库操作错误", e) ;
			throw BusinessException.INFRA_FAILURE ;
		} 
	}

	public void deleteSubAccount (long defaultSubAccountId,long subAccountId) throws BusinessException {
		try {
			this.dao.deleteSubAccount(defaultSubAccountId,subAccountId) ;
			//更新子账户摘要
			this.subAccountDigisters = this.dao.getSubAccountDigisters(account) ;
		} catch (RuntimeException e) {
			log.error(e) ;
			throw BusinessException.INFRA_FAILURE ;
		} 
	}
	
	public void changeDefaultSubAccount (String subAccountId) throws BusinessException {
		try {
			Long id = Long.valueOf(subAccountId) ;
			Account acco = this.dao.findAccountByAccountId(account.getAccountId());
			this.dao.setDefaultSubAccount(acco, id) ;
			//更新内存
			this.defaultSubAccountId = id.longValue() ;
			
		} catch (RuntimeException e) {
			log.error(e) ;
			throw BusinessException.INFRA_FAILURE ;
		} 
	}
	
	public Operator addOrUpdateOperator (Long id ,String operatorId, String name, String mobile, String loginPass, String payPass, String position,String[] operatorSubaccount, String remark,String auditFlag) throws BusinessException {
		try {
			int count = this.dao.findCountOfOperator(this.account.getId().longValue(), operatorId, id) ;
			if (count > 0) {
				throw BusinessException.ACCOUNT_OPRID_DUPLICATED ;
			}
			
			Operator opr = null ;
			if (id == null) {
				opr = new Operator () ;
				opr.setValid(true) ;
				opr.setAccount(this.account) ;
				opr.setCreateUser(this.account.getId().toString()) ;
				opr.setCreateTime(new Date()) ;
				
				if (StringUtils.isNotBlank(operatorId))  { opr.setOperatorId(operatorId) ;}
				if (StringUtils.isNotBlank(name))  { opr.setOperatorName(name) ;}
				if (StringUtils.isNotBlank(mobile))  { opr.setMobile(mobile) ;}
				if (StringUtils.isNotBlank(loginPass))  { opr.setLoginPassword(loginPass) ;}
				if (StringUtils.isNotBlank(payPass))  { opr.setPayPassword(payPass) ;}
				if (StringUtils.isNotBlank(position))  { opr.setPosition(position) ;}
				if (StringUtils.isNotBlank(remark))  { opr.setRemark(remark)  ;}
				if (StringUtils.isNotBlank(auditFlag)) { opr.setAuditFlag(auditFlag);}
			}else {
				opr = this.dao.deleteOperAccount(id);
			}
			opr.setUpdateUser(this.account.getId().toString()) ;
			opr.setUpdateTime(new Date()) ;
			
			int operatorSubaccountLength = operatorSubaccount.length;
			SubAccount subAccount = null;
			Sysbook sysbook = null;

			for(int i=0;i<operatorSubaccountLength;i++) {
				String string = (String)operatorSubaccount[i];
				String[] strings = string.split(":");
				String subAccountId = strings[0];
				String sysBookId = strings[1];
				subAccount = this.dao.getSubAccountById(new Long(subAccountId));
				sysbook = this.dao.getSysBookByTypeIdAndTypeName(sysBookId,OPER_TYPE);
				OperSubacct os = new OperSubacct(new OperSubacctId());
				opr.getOperSubaccts().add(os);
				os.getId().setOperator(opr);
				os.getId().setSubAccount(subAccount);
				os.getId().setSysbook(sysbook);				
			}

			this.dao.addOrUpdateOperator(opr) ;
			
			//更新缓存
			this.loadOperatorList() ;
			
			return opr ;
		} catch (DataAccessException e) {
			log.error("数据库操作错误", e) ;
			throw BusinessException.INFRA_FAILURE ;
		}
	}
	
	public Operator addOrUpdateOper (Long id ,String operatorId, String name, String mobile, String loginPass, String payPass, String position,String remark,String auditFlag) throws BusinessException {
		try {
			int count = this.dao.findCountOfOperator(this.account.getId().longValue(), operatorId, id) ;
			if (count > 0) {
				throw BusinessException.ACCOUNT_OPRID_DUPLICATED ;
			}
			
			Operator opr = null ;
			if (id == null) {
				opr = new Operator () ;
				opr.setValid(true) ;
				opr.setAccount(this.account) ;
				opr.setCreateUser(this.account.getId().toString()) ;
				opr.setCreateTime(new Date()) ;
			}else{
				opr = this.getOperatorById(id.toString());
			}
			
			if (operatorId != null)  { opr.setOperatorId(operatorId) ;}
			if (name != null)  { opr.setOperatorName(name) ;}
			if (mobile != null)  { opr.setMobile(mobile) ;}
			if (loginPass != null)  { opr.setLoginPassword(loginPass) ;}
			if (payPass != null)  { opr.setPayPassword(payPass) ;}
			if (position != null)  { opr.setPosition(position) ;}
			if (remark != null)  { opr.setRemark(remark)  ;}
			if (auditFlag!=null) { opr.setAuditFlag(auditFlag);}
			opr.setUpdateUser(this.account.getId().toString()) ;
			opr.setUpdateTime(new Date()) ;
			
			
			
			this.dao.addOrUpdateOperator(opr) ;
			
			//更新缓存
			this.loadOperatorList() ;
			
			return opr ;
		} catch (DataAccessException e) {
			log.error("数据库操作错误", e) ;
			throw BusinessException.INFRA_FAILURE ;
		}
	}
	
	public Operator getOperatorById (String id) { 
		IMySpaceService service = (IMySpaceService) IPBAppFactory.getObj("mySpaceService");
		return service.getOperatorById(id);
	}
	
	/**
	 * 立即根据id得到操作员
	 * @param id
	 * @return
	 */
	public Operator getOperatorByIdInstance(String id) {
		return this.dao.getOperatorById(new Long(id));
	}

	public void deleteOperator (String subAccountId) throws BusinessException {
		try {
			this.dao.deleteOperator(Long.valueOf(subAccountId)) ;
			//更新操作员摘要
			this.loadOperatorList() ;
		} catch (RuntimeException e) {
			log.error(e) ;
			throw BusinessException.INFRA_FAILURE ;
		} 
	}


	/**
	 * @return Returns the sysLog.
	 */
	public SystemLog getSysLog() {
		return sysLog;
	}


	/**
	 * @param sysLog The sysLog to set.
	 */
	public void setSysLog(SystemLog sysLog) {
		this.sysLog = sysLog;
	}
	
	public void userLogout() throws BusinessException {
		
		if(this.sysLog != null) {
			this.sysLog.setLogoutTime(new Date()) ;
			this.dao.updateLog(this.sysLog) ;
		}
	}


	public Date getLastvisit(){ 
//		List list = new ArrayList();
//		String accountId = sysLog.getAccount().getAccountId();
//		StringBuffer sb = new StringBuffer(); 
//		sb.append("   from SystemLog sl where sl.accountId = :accountId order by loginTime desc ");
//		Query q = getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(sb.toString());
//		q.setFirstResult(0);
//		q.setMaxResults(1);
//		q.setParameter("accountId",accountId);
//		list = q.list();
//		if(list==null){
//			return null;
//		}
//		SystemLog log = (SystemLog)list.get(0);
//		
//		return log.getLoginTime();
		Long id = this.account.getId();
		return this.dao.getLastvisit(id);
	}
	public String getRoot() {
		return root;
	}
	public void setRoot(String root) {
		this.root = root;
	}
	public Account getAccount() {
		return account;
	}
	
}



//private long accountId ;//账户主键
//private String type ;//账户类型
//private String state ; //未激活/修改未确认/工作中
//
//private String accountName ;//账户名称
//private long operatorId ; //操作员主键
//private String operatorName ;//操作员名称
//private List/*String*/ operatorGrants ; //操作员全限
//
//private List /*SubAccountSign*/ subAccounts = new ArrayList () ;  //所有子账户
//private long defaultSubAccount ;//默认子账户
//private long selectedSubAccount ;//当前被选择的子账户
//
//private String email ; //Email
//private String mobile ; //手机
//
//private String password ; //口令
